import java.util.Stack;

/**
 * Cette classe permet la d�claration de constantes, variables et param�tres.
 * Une fois d�clar�s, ces idents sont stock�s dans la Map de TabIdent.
 * 
 * @author Guillaume PANNETIER
 * @author Bertrand LE MAROUILLE
 * @author Quentin DORVEAUX
 * @author Corentin GUICHAOUA
 *
 */
public class Declaration {
	private int offsetVar;
	private int dernierType;
	private Stack <String> pileParam;
	private Stack <Integer> pileTypeParam;
	
	/**
	 * Constructeur de la classe, il initialise l'offset des variables � -2 et instancie les deux piles.
	 */
	public Declaration(){
		offsetVar = -2;
		pileParam = new Stack<String>();
		pileTypeParam = new Stack<Integer>();
	};
	
	/**
	 * Cette m�thode d�clare une constante (IdConst) et la stocke dans la Map de TabIdent.
	 * @param type ENTIER ou BOOLEEN
	 * @param valeur Valeur de la constante
	 * @param nom Nom de la constante
	 */
	public void creerConst(int type, int valeur, String nom){
		try {
			Yaka.tabIdent.rangeIdent(nom, new IdConst(valeur, type));
		} catch (TabIdentException e) {
			Erreur.erreur(e.getMessage());
		}
	}
	
	/**
	 * D�clare une variable (IdVar) et la stocke dans la Map de TabIdent.
	 * Le type de la variable est directement d�duit par Yaka ainsi que son offset.
	 * Une mise � jour de l'offset est �galement effectu�e.
	 * @param nom Nom de la variable � d�clarer.
	 */
	public void creerVar(String nom){
		try {
			Yaka.tabIdent.rangeIdent(nom, new IdVar(offsetVar, dernierType));
			offsetVar -= 2;
		} catch (TabIdentException e) {
			Erreur.erreur(e.getMessage());
		}
	}
	
	/**
	 * Met � jour le dernier type lu par yaka.
	 * @param t Nouveau type.
	 */
	public void setDernierType(int t){
		dernierType = t;
	}
	
	/**
	 * Renvoie le dernier type enregistr�.
	 * @return Dernier type enregistr�.
	 */
	public int getDernierType(){
		return dernierType;
	}
	
	/**
	 * Renvoie l'offset de la prochaine variable.
	 * @return Offset offset de la prochaine variable.
	 */
	public int getOffset(){
		return offsetVar;
	}
	
	/**
	 * D�finit l'offset des variables.
	 * @param off Nouvel offset, s'il est sup�rieur � z�ro, aucun changement n'est effectu�.
	 */
	public void setOffset(int off){
		if(off <= 0)
			offsetVar = off;
	}
	
	/**
	 * D�clare un param�tre (IdParam) et le stocke dans la Map de TabIdent.
	 * @param nom Nom du param�tre
	 * @param offset Offset du param�tre (>=4)
	 */
	public void creerParam(String nom, int offset){
		try {
			Yaka.tabIdent.rangeIdent(nom, new IdParam(offset, pileTypeParam.pop()));
		} catch (TabIdentException e) {
			Erreur.erreur(e.getMessage());
		} catch (Exception e) {
			Erreur.erreur(e.getMessage());
		}
	}
	
	/**
	 * Empile un param�tre en vue d'une d�claration de fonction.
	 * @param nom Nom du param�tre � empiler. Le type du param�tre est d�duit par Yaka.
	 */
	public void empileParam(String nom){
		pileParam.push(nom);
		pileTypeParam.push(dernierType);
	}
	
	/**
	 * Initialise la pile des param�tres � juste avant une d�claration de fonction.
	 */
	public void declParams(){
		int taillePile = pileParam.size();
		for(int i = 0; i < taillePile; i++){
			creerParam(pileParam.pop(), (2*i+4));
		}
	}
	
	/**
	 * Remet l'offset des variables � -2.
	 */
	public void resetOffset(){
		offsetVar = -2;
	}
}
